/*
理解：泛型就是解决 类 接口方法的复用性、以及对不特定数据类型的支持(类型校验)

Dart中的泛型接口:

  实现数据缓存的功能：有文件缓存、和内存缓存。内存缓存和文件缓存按照接口约束实现。

  1、定义一个泛型接口 约束实现它的子类必须有getByKey(key) 和 setByKey(key,value)
  
  2、要求setByKey的时候的value的类型和实例化子类的时候指定的类型一致

*/

// 1. 传过来是 string  T就是String
getData<T>(T value) {
  return value;
}

// 2. 定义泛型类
class MyList<T> {
  List list = <T>[];
  void add(T value) {
    this.list.add(value);
  }

  List getList() {
    print(this.list);
    return list;
  }
}

// 3. 定义抽象类
abstract class Cache<T> {
  // 定义两个抽象方法
  getByKey(String key);
  void setByKey(String key, T value);
}

// 3.1 实现接口 文件缓存
class FileCache<T> implements Cache<T> {
  @override
  getByKey(String key) {
    print('this is getByKey');
  }

  @override
  void setByKey(String key, T value) {
    print('this is setByKey ,key=${key} : value = ${value}');
  }
}

void main() {
  print(getData<String>('你好'));
  // print(getData<int>(12));

  //  创建list 也可以指定元素的类型
  List list = new List<String>.filled(2, "");
  list[0] = "张三1";
  list[1] = "李四";
  print(list);

  List list2 = new List<int>.filled(2, 0);
  list2[0] = 12;
  list2[1] = 13;
  print(list2);

  MyList mylist = new MyList<String>();
  // 这里添加的元素 要和泛型限制的类型对应
  mylist.add('ts');
  mylist.getList();

  // 3.2 接口泛型是对象
  // FileCache file = new FileCache<Map>();
  // file.setByKey('index', {"name": "ts", "age": 20});

  // 3.2 接口泛型是数组
  FileCache file = new FileCache<List>();
  file.setByKey('index', [
    {"name": "ts", "age": 20},
    {"name": "rk", "age": 21},
  ]);
}
